{
  onEnter: function(log, args, state) {
    this.op = args[0];
    this.alg = args[1];
    this.options = args[2];
    this.key = args[3];
    this.keyLength = args[4];
    this.iv = args[5];
    this.dataIn = args[6];
    this.dataInLength = args[7];
    this.dataOut = args[8];
    this.dataOutAvailable = args[9];
    this.dataOutMoved = args[10];

    // 修正 inLength 字段名为 dataInLength
    log('CCCrypt(' +
      'op: ' + this.op + '[0:加密,1:解密]' + ', ' +
      'alg: ' + this.alg + '[0:AES128,1:DES,2:3DES]' + ', ' +
      'options: ' + this.options + '[1:ECB,2:CBC,3:CFB]' + ', ' +
      'key: ' + this.key + ', ' +
      'keyLength: ' + this.keyLength + ', ' +
      'iv: ' + this.iv + ', ' +
      'dataIn: ' + this.dataIn + ', ' +
      'dataInLength: ' + this.dataInLength + ', ' +
      'dataOut: ' + this.dataOut + ', ' +
      'dataOutAvailable: ' + this.dataOutAvailable + ', ' +
      'dataOutMoved: ' + this.dataOutMoved + ')');

    // 检查参数再做hexdump，避免TypeError
    if (this.op == 0) { // 加密时dump输入
      if (this.dataIn && this.dataInLength) {
        log("dataIn:");
        try {
          log(hexdump(ptr(this.dataIn), {
            length: this.dataInLength.toInt32(),
            header: true,
            ansi: true
          }));
        } catch (e) { log("[hexdump dataIn error] " + e); }
      } else {
        log("dataIn or dataInLength undefined/null");
      }

      if (this.key && this.keyLength) {
        log("key:");
        try {
          log(hexdump(ptr(this.key), {
            length: this.keyLength.toInt32(),
            header: true,
            ansi: true
          }));
        } catch (e) { log("[hexdump key error] " + e); }
      } else {
        log("key or keyLength undefined/null");
      }

      if (this.iv && this.keyLength) {
        log("iv:");
        try {
          log(hexdump(ptr(this.iv), {
            length: this.keyLength.toInt32(),
            header: true,
            ansi: true
          }));
        } catch (e) { log("[hexdump iv error] " + e); }
      } else {
        log("iv or keyLength undefined/null");
      }
    }
  },

  onLeave: function(log, retval, state) {
    // 解密时dump输出和密钥
    // 注意：dataOutMoved 需要为内存指针
    var dataOutLen = 0;
    try {
      dataOutLen = (this.dataOutMoved && typeof this.dataOutMoved.toInt32 === 'function')
        ? Memory.readUInt(this.dataOutMoved)
        : 0;
    } catch (e) {
      log("[Memory.readUInt(dataOutMoved) error] " + e);
      dataOutLen = 0;
    }

    log("dataOut:");
    if (this.dataOut && dataOutLen > 0) {
      try {
        log(hexdump(ptr(this.dataOut), {
          length: dataOutLen,
          header: true,
          ansi: true
        }));
      } catch (e) { log("[hexdump dataOut error] " + e); }
    } else {
      log("dataOut pointer undefined/null or data length zero");
    }

    if (this.op == 1) {
      if (this.key && this.keyLength) {
        log("key:");
        try {
          log(hexdump(ptr(this.key), {
            length: this.keyLength.toInt32(),
            header: true,
            ansi: true
          }));
        } catch (e) { log("[hexdump key error] " + e); }
      } else {
        log("key or keyLength undefined/null");
      }
      if (this.iv && this.keyLength) {
        log("iv:");
        try {
          log(hexdump(ptr(this.iv), {
            length: this.keyLength.toInt32(),
            header: true,
            ansi: true
          }));
        } catch (e) { log("[hexdump iv error] " + e); }
      } else {
        log("iv or keyLength undefined/null");
      }
    }

    log("CCCrypt did finish");
  }
}